package cn.uniquetech.db2;

import java.util.List;

import cn.uniquetech.util.FileUtil;
import cn.uniquetech.util.StrUtil;

public class DB2Util {

	private static String xmlStr = "";
	private static String headerStr = "\t";
	private static String tailStr = "\r\n";
	private static String entity = "";
	// 要过滤的字段
	private static String filterFields = ",ccode,iid,ipid,cname,ccomment,adduid,adduname,adddate,addudeptid,addudeptname,addudeptcode,edituid,edituname,editdate,editudeptid,editudeptname,editudeptcode";
	// 主键
	private static String key = "iid";

	/**
	 * 
	 * @param packageName
	 *            包名
	 * @param tableName
	 *            表名
	 * @param colNames
	 *            字段集合
	 * @return
	 */
	public static String paraseSql(String packageName, String tableName, List<String> colNames) {

		String servicePackage = packageName + ".entity.sqlmap";
		String capName = StrUtil.initCap(tableName);
		capName = capName.substring(0, capName.length() - 1);
		String entityName = packageName + ".entity." + capName + entity;// +
																		// "Entity";
		xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + tailStr;
		xmlStr += "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">" + tailStr;
		xmlStr += "<mapper namespace=\"" + capName + "Mapper\">" + tailStr;

		// addEntity
		xmlStr += headerStr + "<!-- 插入实体 -->" + tailStr;
		xmlStr += headerStr + "<insert id=\"addEntity\" parameterType=\"" + entityName + "\">" + tailStr;
		xmlStr += headerStr + " " + genInsertSqlStr(tableName, colNames) + tailStr;
		xmlStr += headerStr + "</insert>" + tailStr;

		// updateEntity
		xmlStr += headerStr + "<!-- 更新实体 -->" + tailStr;
		xmlStr += headerStr + "<update id=\"updateEntity\" parameterType=\"" + entityName + "\">" + tailStr;
		xmlStr += headerStr + " " + genUpdateSqlStr(tableName, colNames) + tailStr;
		xmlStr += headerStr + "</update>" + tailStr;

		// deleteEntity
		xmlStr += headerStr + "<!-- 删除实体-->" + tailStr;
		xmlStr += headerStr + "<delete id=\"deleteEntity\" parameterType=\"" + entityName + "\">" + tailStr;
		xmlStr += headerStr + " delete from " + tableName + " where " + key + " = #{" + key + "}" + tailStr;
		xmlStr += headerStr + "</delete>" + tailStr;
		// deleteEntity
		xmlStr += headerStr + "<!-- 删除多个实体-->" + tailStr;
		xmlStr += headerStr + "<delete id=\"deleteEntities\" parameterType=\"string\">" + tailStr;
		xmlStr += headerStr + " delete from " + tableName + " where " + key + " in (${_parameter})" + tailStr;
		xmlStr += headerStr + "</delete>" + tailStr;

		// fecthOneEntity
		xmlStr += headerStr + "<!-- 获取单个实体 -->" + tailStr;
		xmlStr += headerStr + "<select id=\"fecthOneEntity\" parameterType=\"" + entityName + "\" resultType=\"" + entityName + "\">" + tailStr;
		xmlStr += headerStr + " select * from " + tableName + " where " + key + " = #{" + key + "}" + tailStr;
		xmlStr += headerStr + "</select>" + tailStr;

		// queryEntities
		xmlStr += headerStr + "<!-- 查询实体集合 -->" + tailStr;
		xmlStr += headerStr + "<select id=\"queryEntities\" parameterType=\"" + entityName + "\" resultType=\"" + entityName + "\">" + tailStr;
		xmlStr += headerStr + " select * from " + tableName + " order by " + key + " desc" + tailStr;
		xmlStr += headerStr + "</select>" + tailStr;

		// 分页查询
		xmlStr += headerStr + "<!-- 分页查询 -->" + tailStr;
		xmlStr += headerStr + "<select id=\"queryDataGrid\" parameterType=\"" + entityName + "\" resultType=\"" + entityName + "\">" + tailStr;
		xmlStr += headerStr + "select A.* from (select row_number() over(order by iid desc) as rownum," + tableName + ".* from " + tableName + " where 1=1 <if test=\"startdate !=null and startdate !='' \"> and adddate &gt;= #{startdate}</if><if test=\"enddate !=null and enddate !='' \"> and adddate &lt;= #{enddate}</if> ) A where A.rownum &gt;#{start} and A.rownum &lt;= #{end} " + tailStr;
		xmlStr += headerStr + "</select>" + tailStr;

		xmlStr += headerStr + "<select id=\"queryDataGrid_count\" parameterType=\"" + entityName + "\" resultType=\"int\">" + tailStr;
		xmlStr += headerStr + " select count(*) from " + tableName +" where 1=1 <if test=\"startdate !=null and startdate !='' \"> and adddate &gt;= #{startdate}</if><if test=\"enddate !=null and enddate !='' \"> and adddate &lt;= #{enddate}</if> " + tailStr;
		xmlStr += headerStr + "</select>" + tailStr;

		xmlStr += "</mapper>";
		FileUtil.writeFile(servicePackage, capName + ".xml", xmlStr);
		return xmlStr;
	}

	public static String genInsertSqlStr(String tableName, List<String> colNames) {
		String sqlStr = "insert into " + tableName + " (";
		String fields = "";
		String values = "";

		for (String colName : colNames) {
			if (key.equals(colName)) {
				continue;
			}
			fields += colName + ",";
			values += "#{" + colName + "},";
		}

		fields = fields.substring(0, fields.length() - 1);
		values = values.substring(0, values.length() - 1);
		sqlStr += fields + ") " + tailStr;
		sqlStr += headerStr + " values " + tailStr;
		sqlStr += headerStr + "(" + values + ")";
		return sqlStr;
	}

	public static String genUpdateSqlStr(String tableName, List<String> colNames) {
		String sqlStr = "update " + tableName + " set ";

		String fields = "";

		for (String colName : colNames) {
			if (key.equals(colName) || "adduid".equals(colName) || "adduname".equals(colName) || "adddate".equals(colName)) {
				continue;
			}
			fields += colName + "=#{" + colName + "},";
		}

		fields = fields.substring(0, fields.length() - 1);
		sqlStr += fields + "\r\n";
		sqlStr += headerStr + " where " + key + " =#{" + key + "}";
		return sqlStr;
	}

	public static String sqlType2JavaType(String sqlType) {

		if (sqlType.equalsIgnoreCase("bit")) {
			return "boolean";
		} else if (sqlType.equalsIgnoreCase("tinyint")) {
			return "byte";
		} else if (sqlType.equalsIgnoreCase("smallint")) {
			return "short";
		} else if (sqlType.equalsIgnoreCase("integer")) {
			return "int";
		} else if (sqlType.equalsIgnoreCase("bigint")) {
			return "long";
		} else if (sqlType.equalsIgnoreCase("float")) {
			return "float";
		} else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric") || sqlType.equalsIgnoreCase("real") || sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")) {
			return "double";
		} else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("text")) {
			return "String";
		} else if (sqlType.equalsIgnoreCase("date") || sqlType.equalsIgnoreCase("timestamp")) {
			return "Date";
		} else if (sqlType.equalsIgnoreCase("image")) {
			return "Blod";
		} else {
			return "";
		}
	}

	public static void getAllAttrs(StringBuffer sb, List<String> colNames, List<String> colTypes) {

		for (int i = 0; i < colNames.size(); i++) {
			String colName = colNames.get(i).toLowerCase().trim();
			if (filterFields.indexOf(","+colName) != -1) {
				continue;
			}
			sb.append("\tprivate " + sqlType2JavaType(colTypes.get(i)) + " " + colNames.get(i) + ";\r\n");
			sb.append(genSetGet(sqlType2JavaType(colTypes.get(i)), colNames.get(i)));
		}
	}

	// 生成set get
	private static String genSetGet(String colType, String colName) {
		String str = "";
		String capName = captureName(colName);
		str += "public " + colType + " get" + capName + "(){return " + colName + ";}" + tailStr;
		str += "public void set" + capName + "(" + colType + " " + colName + "){this." + colName + "=" + colName + ";}" + tailStr;
		return str;
	}

	// 首字母变大
	public static String captureName(String name) {
		char[] cs = name.toCharArray();
		cs[0] -= 32;
		return String.valueOf(cs);
	}

	public static String parseEntity(String packageName, String tableName, List<String> colNames, List<String> colTypes, int[] colSizes) {
		String servicePackage = packageName + ".entity";
		StringBuffer sb = new StringBuffer();
		sb.append("package " + servicePackage + ";\r\n");
		sb.append("\r\n");
		sb.append("import cn.uniquetech.entity.base.BaseEntity;\r\n");

		String clazz = StrUtil.initCap(tableName);
		clazz = clazz.substring(0, clazz.length() - 1);
		sb.append("@SuppressWarnings(\"serial\")" + "\r\n");
		sb.append("public class " + clazz + entity + " extends BaseEntity" + " {\r\n");
		getAllAttrs(sb, colNames, colTypes);
		sb.append("}\r\n");

		FileUtil.writeFile(servicePackage, clazz + entity + ".java", sb.toString());
		return sb.toString();
	}

	// service 生成接口
	public static String parseServiceInterface(String packageName, String tableName) {
		String servicePackage = packageName + ".service";
		StringBuffer sb = new StringBuffer();
		sb.append("package " + servicePackage + ";\r\n");
		String clazz = StrUtil.getSimpleClassName(tableName, true);
		sb.append("import cn.uniquetech.service.base.IBaseService;\r\n");
		sb.append("\r\n\r\npublic interface I" + clazz + "Service extends IBaseService" + "{\r\n\r\n");
		sb.append("}\r\n");
		FileUtil.writeFile(servicePackage, "I" + clazz + "Service.java", sb.toString());
		return sb.toString();
	}

	// service 生成实现类
	public static String parseServiceClass(String packageName, String tableName) {
		String servicePackage = packageName + ".service.impl";
		StringBuffer sb = new StringBuffer();
		sb.append("package " + servicePackage + ";\r\n\r\n");
		String clazz = StrUtil.getSimpleClassName(tableName, true);
		sb.append("import org.springframework.stereotype.Service;\r\n");
		sb.append("import cn.uniquetech.service.I" + clazz + "Service;");
		sb.append("\r\n\r\n");
		sb.append("@Service");
		sb.append("\r\n");
		sb.append("public class " + clazz + "ServiceImpl extends BaseServiceImpl implements I" + clazz + "Service" + " {\r\n\r\n");
		// sb.append("private I" + clazz + "Service " + clazz.toLowerCase() +
		// "Service;\r\n");
		sb.append("public " + clazz + "ServiceImpl() {\r\n");
		sb.append("\t\tsuper();\r\n");
		sb.append("\t\tthis.mapper = \"" + clazz + "Mapper\";\r\n");
		sb.append("\t}\r\n");
		sb.append("}\r\n");
		FileUtil.writeFile(servicePackage, clazz + "ServiceImpl.java", sb.toString());
		return sb.toString();
	}

	// 生成 controller
	public static String parseControllerClass(String packageName, String tableName) {
		String servicePackage = packageName + ".controller";
		String clazz = StrUtil.getSimpleClassName(tableName, true);
		StringBuffer sb = new StringBuffer();
		sb.append("package " + servicePackage + ";\r\n\r\n");
		sb.append("import org.springframework.beans.factory.annotation.Autowired;\r\n");
		sb.append("import org.springframework.stereotype.Controller;\r\n");
		sb.append("import org.springframework.web.bind.annotation.RequestMapping;\r\n");
		sb.append("import cn.uniquetech.controller.base.BaseController;\r\n");
		sb.append("import cn.uniquetech.entity." + clazz + entity + ";\r\n");
		sb.append("import cn.uniquetech.service.I" + clazz + "Service;\r\n");
		sb.append("\r\n");
		sb.append("@Controller");
		sb.append("\r\n");
		sb.append("@SuppressWarnings(\"unused\")");
		sb.append("\r\n");
		sb.append("@RequestMapping(value = \"/" + clazz.toLowerCase() + "\")");
		sb.append("\r\n");
		sb.append("public class " + clazz + "Controller extends BaseController<" + clazz + entity + ">" + "{\r\n\r\n");
		sb.append("private I" + clazz + "Service " + clazz.toLowerCase() + "Service;" + "\r\n");
		sb.append("@Autowired\r\n");
		sb.append("public " + clazz + "Controller(I" + clazz + "Service " + clazz.toLowerCase() + "Service) {\r\n");
		sb.append("\t\tsuper();\r\n");
		sb.append("\t\t" + "this." + clazz.toLowerCase() + "Service = " + clazz.toLowerCase() + "Service;" + "\r\n");
		sb.append("\t\t" + "this.baseService = " + clazz.toLowerCase() + "Service;" + "\r\n");
		sb.append("\t\t" + "this.ctrlModel = \"" + clazz.toLowerCase() + "\";" + "\r\n");
		sb.append("\t\t" + "this.ctrlName = \"" + clazz.toLowerCase() + "\";\r\n");
		// sb.append("\t\t" + "this.indexUrl = \"" + clazz.toLowerCase() +
		// "/index" + "\";\r\n");
		sb.append("\t}\r\n");
		sb.append("}\r\n");
		FileUtil.writeFile(servicePackage, clazz + "Controller.java", sb.toString());
		return sb.toString();
	}

	// 生成view试图 sb.append(""+tailStr);
	private static String htmlTailStr = "\r\n";

	private static String paraseView(String packageName, List<String> colNames, List<String> colTypes, String tableName, List<String> remarks) {
		StringBuffer sb = new StringBuffer();
		sb.append("<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%>" + htmlTailStr);
		sb.append("<!DOCTYPE html>" + htmlTailStr + "<html>" + htmlTailStr + "<head>" + htmlTailStr);
		sb.append("<%@include file=\"/context/pageheader.jsp\"%>" + htmlTailStr);
		sb.append("<script type=\"text/javascript\" src=\"<%=basePath%>/jslib/GridViewUtil.js\"></script>" + htmlTailStr);
		sb.append("</head>" + htmlTailStr + "<body>" + htmlTailStr);
		sb.append("<div id=\"dgtoolbar\" class=\"datagrid-toolbar\"><%@include file=\"/jsp/pub/GridToolBar.jsp\"%></div>" + htmlTailStr);

		// --------------
		sb.append("<table id=\"dg\" class=\"easyui-datagrid\" data-options=\"url:'queryDataGrid.do',idField:'iid',rownumbers:true,singleSelect:false,method:'post',toolbar:'#dgtoolbar',pagination:true,pageSize:20,pageList:[20,30,50],fit:true\"><thead>" + htmlTailStr);
		sb.append("<thead><tr>" + htmlTailStr);
		sb.append("<th data-options=\"field:'iid'\" checkbox=\"true\"></th>" + htmlTailStr);
		int colSize = colNames.size();
		for (int i = 0; i < colSize; i++) {
			String colName = colNames.get(i);
			String remark = remarks.get(i);
			String colType = colTypes.get(i).trim();
			System.out.println("coltype------>"+colType);
			if (key.equals(colName)) {
				continue;
			}
			if ("date".equalsIgnoreCase(colType) || "timestamp".equalsIgnoreCase(colType)) {
				sb.append("<th formatter=\"Common.dateTime\" data-options=\"field:'" + colName + "'\" 	width=\"60\" align=\"center\">" + remark + "</th>" + htmlTailStr);
			} else {
				sb.append("<th data-options=\"field:'" + colName + "'\" 	width=\"60\" align=\"center\">" + remark + "</th>" + htmlTailStr);
			}
		}
		sb.append("</tr></thead></table>" + htmlTailStr);

		// -------------
		sb.append("<div id=\"dlg\" class=\"easyui-dialog\" title=\"操作\" style=\"padding:5px\" data-options=\"buttons: '#dlg-buttons',closed:'true',modal:true\">" + htmlTailStr);
		sb.append("<form id=\"dataform\" method=\"post\">" + htmlTailStr + "<table>" + htmlTailStr);
		sb.append("<tr><td>名称:</td><td><input name=\"iid\" id=\"iid\" type=\"hidden\"></input>" + htmlTailStr + "<input name=\"cname\" class=\"easyui-textbox\" style=\"width: 200px\" data-options=\"required:true\"></input></td></tr>" + htmlTailStr);

		for (int i = 0; i < colSize; i++) {
			String colName = colNames.get(i);
			String remark = remarks.get(i);
			if (key.equals(colName) || "cname".equals(colName)) {
				continue;
			}
			sb.append("<tr><td>" + remark + ":</td><td><input name=\"" + colName + "\" class=\"easyui-textbox\" style=\"width: 200px\"></input></td></tr>" + htmlTailStr);
		}
		sb.append("</table></form></div>");

		sb.append("<div id=\"dlg-buttons\">" + htmlTailStr);
		sb.append("<a id=\"dlg-savebtn\" 	href=\"javascript:void(0)\" style=\"width:50\" class=\"easyui-linkbutton\" iconCls=\"icon-ok\">保存</a>" + htmlTailStr);
		sb.append("<a id=\"dlg-closebtn\" 	href=\"javascript:void(0)\" style=\"width:50\" class=\"easyui-linkbutton\" iconCls=\"icon-no\">关闭</a>" + htmlTailStr);
		sb.append("</div>" + htmlTailStr);

		sb.append("</body></html>");
		String clazz = StrUtil.getSimpleClassName(tableName, true).toLowerCase();
		String servicePackage = packageName + ".jsp." + clazz;
		FileUtil.writeFile(servicePackage, "index.jsp", sb.toString());
		return sb.toString();
	}

	public static String sc(String packageName, String tableName, List<String> colNames, List<String> colTypes, List<String> remarks, int[] colSizes) {
		String result = "";
		result += paraseSql(packageName, tableName, colNames);
		result += parseEntity(packageName, tableName, colNames, colTypes, colSizes);
		result += parseServiceClass(packageName, tableName);
		result += parseControllerClass(packageName, tableName);
		result += parseServiceInterface(packageName, tableName);
		result += paraseView(packageName, colNames, colTypes, tableName, remarks);
		return result;
	}

}
